<?php

namespace App\Http\Controllers\Sip;

use App\Consts\ResponseConsts\ResponseStatusConsts;
use App\Func\RequestFunc;
use App\Func\ResponseFunc;
use App\Func\TokenFuc;
use App\Models\MeLawCase\MeLawCase;
use App\Models\MeLawCase\MeLawCasePhoneModel;
use App\Models\Mis\MisNewCasePhoneLogModel;
use App\Models\Staff\StaffModel;
use Exception;
use Illuminate\Http\Exceptions\HttpResponseException;

class MisController
{
    protected $xmlRequest = '<?xml version="1.0" encoding="UTF-8"?>';

    protected string $url = 'http://175.152.51.170:4481';

    public function getDeviceInfo()
    {
        $xmlData = $this->xmlRequest . '
         <Control attribute="Query"><DeviceInfo/></Control>';

        $xml = (new RequestFunc())->xmlGet($this->url, $xmlData);
        // 打印所有设备（ext节点）
        $lines = [];
        foreach ($xml->devices->ext as $ext) {
            $lineid = (string)$ext['lineid'];
            if (strpos($lineid, 'IPPhone') !== false) {
                $lines[] = [
                    'key' => "IP电话" . (string)$ext['id'],
                    'value' => (string)$ext['id'],
                ];
            }
        }
        return ResponseFunc::returnJson(
            'ok',
            $lines,
            '操作成功',
            ResponseStatusConsts::OK_200_RESPONSE_STATUS
        );

    }


    public function getExtInfo()
    {
        $extId = request()->post('extId', '');
        if (!$extId) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "extId不能为空",
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }

        $xmlData = $this->xmlRequest . '
        <Control attribute="Query"><ext id="' . $extId . '"/></Control>';

        $xml = (new RequestFunc())->xmlGet($this->url, $xmlData) ?? null;
        if (!$xml) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "坐席不存在",
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }


        return ResponseFunc::returnJson(
            'ok',
            [
                'no_disturb' => (string)$xml->ext->No_Disturb ?? 'off',
                'record' => (string)$xml->ext->record ?? '',
                'state' => (string)$xml->ext->state ?? '',
                'stateStr' => $this->getMisState($xml->ext->state),
            ],
            '操作成功',
            ResponseStatusConsts::OK_200_RESPONSE_STATUS
        );

    }

    public function getMisCallStatus(){
        $statusId = request()->post('status_id', '');
        $xmlData = $this->xmlRequest . '<Control attribute="Query"><outer id="'.$statusId.'"/></Control>';
        $xml = (new RequestFunc())->xmlGet($this->url, $xmlData) ?? null;
        if (!$xml) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "拨号不存在",
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }

        $stateStr = "";
        switch (strtolower((string)$xml->outer->state)){
            case "talk":
                $stateStr =  "通话中";
                break;
            case "progress":
                $stateStr = " 振铃、回铃或通话中";
                break;
            case "wait":
                $stateStr = "呼叫中";
                break;
            default:
                $stateStr = "未知状态";
        }
        return ResponseFunc::returnJson(
            'ok', [
                'status' => (string)$xml->outer->state,
                'status_str' => $stateStr
            ],
            '操作成功',
            ResponseStatusConsts::OK_200_RESPONSE_STATUS
        );
    }

    public function getMisState($state)
    {
        switch (strtolower($state)) {
            case "ready":
                return "空闲可用";
            case "active":
                return " 振铃、回铃或通话中";
            case "progress":
                return "模拟分机摘机后等待拨号、拨号过程中";
            case "offline":
                return "离线";
            case "offhook":
                return "催挂";
        }
    }

    public function bindMsi()
    {
        $staffId = request()->post('staff_id', 0);
        $msiCode = request()->post('msi_seats_number', '');
        if (!$staffId) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "staff_id不能为空",
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
        if (!$msiCode) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "msi_seats_number不能为空",
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
        $staffModel = new StaffModel();
        // 校验当前分机号和密码是否已经绑定过
        $isExists = $staffModel->withoutGlobalScopes()->where('staff_seats_number', $msiCode)
            ->where('staff_id', '!=', $staffId)
            ->first();

        if ($isExists) {
            return ResponseFunc::returnJson(
                'error',
                null,
                '当前分机号已被绑定',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS
            );
        }
        $staffModel->withoutGlobalScopes()->where('staff_id', $staffId)->update([
            'staff_seats_number' => $msiCode
        ]);
        return ResponseFunc::returnJson(
            'ok',
            null,
            '绑定分机成功',
            ResponseStatusConsts::OK_200_RESPONSE_STATUS
        );
    }

    public function unlockMsi()
    {
        $staffId = request()->post('staff_id', 0);
        if (!$staffId) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "staff_id不能为空",
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
        $staffModel = new StaffModel();

        $staffModel->withoutGlobalScopes()->where('staff_id', $staffId)->update([
            'staff_seats_number' => ''
        ]);
        return ResponseFunc::returnJson(
            'ok',
            null,
            '解绑分机成功',
            ResponseStatusConsts::OK_200_RESPONSE_STATUS
        );
    }

    public function getCaseWhLog(){
        $caseId = request()->post('caseId', '');
        $data = MisNewCasePhoneLogModel::withoutGlobalScopes()->where('case_id',$caseId)->get()->toArray();
        $callIds = array_column($data,'call_id');
        $resData = MisNewCasePhoneLogModel::withoutGlobalScopes()->whereIn('call_id',$callIds)->orderBy('id','desc')->get()->toArray();
        $res = [];
        foreach($resData as $datum){
            $res[] = $datum;
        }
        return ResponseFunc::returnJson(
            'ok',
            $res,
            '操作成功',
            ResponseStatusConsts::OK_200_RESPONSE_STATUS
        );
    }

    public function callPhone()
    {
        $caseId = request()->post('caseId', '');
        $meLawCaseModel = new MeLawCase();
        $mainId = $meLawCaseModel->withoutGlobalScopes()->select(['main_respondent_phone_id'])->where('law_case_id', $caseId)->where('status', 1)->first();
        if (!$mainId) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '主叫号码未配置',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS
            ));
        }
        $lawCasePhoneModel = new MeLawCasePhoneModel();
        $lawCasePhone = $lawCasePhoneModel->select(['phone_number', 'is_wd'])->where('law_case_phone_id', $mainId['main_respondent_phone_id'] ?? 0)->first();

        if (!$lawCasePhone) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '主叫号码异常',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS
            ));
        }
        $currentStaffInfo = TokenFuc::getCurrentStaffInfo();
        if (!$currentStaffInfo) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '当前用户未登录',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS
            ));
        }
        $staffModel = new StaffModel();
        $staffInfo = $staffModel->select(['staff_seats_number'])->where('staff_id', $currentStaffInfo['staff_id'] ?? 0)->first();
        if (!$staffInfo) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '当前用户未绑定分机',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS
            ));
        }
        $msi_seats_number = $staffInfo['staff_seats_number'] ?? '';

        if (!$msi_seats_number) {
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '分机号错误',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS
            ));
        }
        $phone = $lawCasePhone['phone_number'];
        $isWd = request()->post('is_wd', '');
        if($isWd == 1 ){
            $phone = '0' . $phone;
        }else{
            if ($lawCasePhone['is_wd'] == 1) {
                $phone = '0' . $phone;
            }
        }

        $xmlData = $this->xmlRequest . '<?xml version="1.0" encoding="utf-8" ?>
<Transfer attribute="Connect">
<ext id="' . $msi_seats_number . '"/>
<outer to="' . $phone . '"/>
</Transfer>';

        $xml = (new RequestFunc())->xmlGet('http://175.152.51.170:4481', $xmlData);
        if ((string)$xml->err['code']) {
            switch ($xml->err['code']) {
                case '2':
                    $msg = '主叫的呼叫权限受限';
                    break;
                case '3':
                    $msg = '被叫分机不在线';
                    break;
                case '4':
                    $msg = '被叫分机当前正在和其他终端通话';
                    break;
                case '5':
                    $msg = '中继线资源不足，无法执行外呼';
                    break;
                case '6':
                    $msg = '被叫分机忙线';
                    break;
                case '7':
                    $msg = '分机不存在';
                    break;
                case '8':
                    $msg = '主叫分机自身不在线';
                    break;
                case '1':
                default:
                    $msg = '系统异常';
                    break;
            }
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '拨号异常' . $msg,
                ResponseStatusConsts::OK_200_RESPONSE_STATUS
            ));
        }

        MisNewCasePhoneLogModel::insert([
            'case_id' => $caseId,
            'call_id' => (string)$xml->outer['callid'] ?? "",
            'owner_id' => $currentStaffInfo['staff_id'] ?? 0,
            'created_at' => date('Y-m-d H:i:s')
        ]);

        return ResponseFunc::returnJson(
            'ok',
            [
                'callid' => (string)$xml->outer['callid'] ?? "",
                'status_id' => (string)$xml->outer['id'] ?? "",
            ],
            '操作成功',
            ResponseStatusConsts::OK_200_RESPONSE_STATUS
        );

    }

// 1. 接收并处理不同格式的输入数据
    function getRequestDatax()
    {
        $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
        $isXml = stripos($contentType, 'xml') !== false;

        // 处理XML输入（如Content-Type为application/xml）
        if ($isXml) {
            return [
                'type' => 'xml',
                'raw_data' => file_get_contents('php://input')
            ];
        }

        // 处理普通参数（GET/POST/COOKIE）
        $data = [
            'type' => 'params',
            'get' => $_GET,
            'post' => $_POST,
            'cookies' => $_COOKIE,
            'files' => $_FILES
        ];

        // 处理JSON输入（如Content-Type为application/json）
        $jsonInput = json_decode(file_get_contents('php://input'), true);
        if (json_last_error() === JSON_ERROR_NONE) {
            $data['json'] = $jsonInput;
        }

        return $data;
    }

    public function callBack()
    {
        // 获取原始请求内容
        $rawInput = file_get_contents('php://input');

        // 尝试解析XML（如果是XML请求）
        $xmlData = null;
        if (!empty($rawInput)) {
            // 检查内容类型是否为XML
            $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
            if (stripos($contentType, 'xml') !== false || $this->isXml($rawInput)) {
                // 尝试解析XML
                libxml_use_internal_errors(true);
                $xml = simplexml_load_string($rawInput);
                if ($xml !== false) {
                    $xmlData = $rawInput; // 保存原始XML字符串
                } else {
                    // XML解析失败，记录错误
                    $errors = libxml_get_errors();
                    $xmlData = "无效的XML: " . print_r($errors, true);
                }
            }
        }

        $requestData = [
            'timestamp' => date('Y-m-d H:i:s'),
            'client_ip' => $_SERVER['REMOTE_ADDR'] ?? 'Unknown',
            'method' => $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN',
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'None',
            'content_type' => $_SERVER['CONTENT_TYPE'] ?? 'None',
            'payload' => $xmlData !== null ? $xmlData : $this->getRequestData()  // 优先使用XML数据
        ];



        // 格式化日志内容
        $logContent = "========== 请求记录 ==========\n";
        foreach ($requestData as $key => $value) {
            $logContent .= "[$key]: " .
                (is_array($value) ? print_r($value, true) : $value) . "\n";
        }
        $logContent .= "==============================\n\n";

        $logFile = __DIR__ . '/1.txt';

        // 安全写入文件（不移除htmlspecialchars，但不再使用它）
        try {
            // 直接写入原始数据，不进行转义
            $result = file_put_contents(
                $logFile,
                $logContent,  // 移除了htmlspecialchars
                FILE_APPEND | LOCK_EX
            );

            if ($result === false) {
                throw new Exception('文件写入失败：请检查权限或磁盘空间');
            }

            if (!empty($rawInput)) {
                libxml_use_internal_errors(true);
                $xml = simplexml_load_string($rawInput);


                if ($xml !== false) {
                    if((string)$xml->attributes()->attribute !== null && (string)$xml->Type == null){
                        // 提取 attribute 和 callid
                        $result = [
                            'attribute' => (string)$xml->attributes()->attribute,
                            'callid' => (string)$xml->outer->attributes()->callid ?? 0
                        ];
                        $attr = $result['attribute'];
                        $status = '';
                        switch ($attr){
                            case 'RING':
                                $status = '振铃';
                                break;
                            case 'ALERT':
                                $status = '回铃';
                                break;
                            case 'ANSWER':
                                $status = '分机应答';
                                break;
                            case 'ANWERED':
                                $status = '话机应答';
                                break;
                            case 'BUSY':
                                $status = '分机忙';
                                break;
                            case 'IDLE':
                                $status = '分机空闲';
                                break;
                            case 'DIVERT':
                                $status = '呼叫转移';
                                break;
                            case 'BYE':
                                $status = '挂断';
                                break;
                        }
                        if(!empty($result['callid'])){
                            MisNewCasePhoneLogModel::withoutGlobalScopes()->insert([
                                'case_id' => 0,
                                'call_id' => $result['callid'],
                                'call_status' => $status,
                                'created_at' => date('Y-m-d H:i:s')
                            ]);
                        }
                    }
                    if((string)$xml->Type !== null){
                        $status = '';
                        switch ((string)$xml->Type){
                            case 'IN':
                                $status = '呼入';
                                break;
                            case 'OU':
                                $status = '呼出';
                                break;
                        }
                        $callId = (string)$xml->callid ?? 0;
                        if(!empty($callId)){
                            MisNewCasePhoneLogModel::withoutGlobalScopes()->insert([
                                'case_id' => 0,
                                'call_id' => $callId,
                                'call_status' => $status,
                                'created_at' => date('Y-m-d H:i:s')
                            ]);
                        }

                    }

                } else {
                    header('Content-Type: application/json');
                    echo json_encode(['status' => 'err', 'message' => '解析错误']);
                }
            } else {
                header('Content-Type: application/json');
                echo json_encode(['status' => 'err', 'message' => 'X解析错误:']);
            }
            // 返回成功响应
            header('Content-Type: application/json');
            echo json_encode(['status' => 'success', 'message' => '数据已保存']);

        } catch (Exception $e) {
            header('HTTP/1.1 500 Internal Server Error');
            echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
        }
    }

    // 辅助函数：检查字符串是否为XML
    public function isXml($string)
    {
        // 简单检查是否以XML声明或标签开头
        return preg_match('/^\s*<\?xml|^\s*<[a-zA-Z]/', $string);
    }

    // 如果getRequestData方法不能处理原始输入，可以修改它或添加以下方法
    public function getRequestData()
    {
        // 尝试获取原始输入作为备用
        $rawInput = file_get_contents('php://input');
        if (!empty($rawInput)) {
            return $rawInput;
        }

        // 如果没有原始输入，返回POST或GET数据
        return !empty($_POST) ? $_POST : $_GET;
    }

}